/*
 * @Author: sonss
 * @Date: 2024-08-27 11:08:36
 * @LastEditTime: 2024-09-03 21:50:31
 * @FilePath: /ss-file-antd/src/components/Upload/Button.tsx
 * @Description:  上传按钮
 */
import { Submit } from '@/services/upload';
import { CloudUploadOutlined } from '@ant-design/icons';
import { Button, message, Upload } from 'antd';
import { SizeType } from 'antd/es/config-provider/SizeContext';
import { UploadChangeParam } from 'antd/es/upload';
import { UploadFile, UploadProps } from 'antd/lib';
import { RcFile } from 'antd/lib/upload';
import { ReactNode } from 'react';

type ButtonUploadProps = {
  multiple?: boolean;
  value?: string | string[];
  btnTitle?: string;
  btnChild?: ReactNode;
  btnSize?: SizeType;
  showUploadList?: boolean;
  disabled?: boolean;
  onChange?: (file: UPLOADER.FileInfo) => void;
  onLoad?: (loading: boolean) => void;
  onError?: () => void;
};

const ButtonUpload: React.FC<ButtonUploadProps> = (props) => {
  const [messageApi, contextHolder] = message.useMessage();

  const handleChange: UploadProps['onChange'] = (info: UploadChangeParam<UploadFile>) => {
    if (info.file.status === 'uploading') {
      if (props.onLoad) {
        props.onLoad(true);
      }
    } else if (info.file.status === 'done') {
      const files = info.file?.response?.data?.files || [];
      if (props.onChange) {
        const file = files.length > 0 ? files[0] : {};
        props.onChange(file);
      }

      // 全部完成
      if (props.onLoad) {
        const okAll = info.fileList.every((f) => f.status === 'done');
        if (okAll) {
          props.onLoad(false);
        }
      }
    } else if (info.file.status === 'error') {
      if (props.onError) {
        props.onError();
      }
    }
  };

  const handleCustomRequest = async (config: any) => {
    const options = {
      onUploadProgress: (ev: any) => {
        const p = Math.round((ev.loaded * 100) / ev.total!);
        config.onProgress(p);
      },
    };

    try {
      const formData = new FormData();
      formData.append('files[]', config.file);

      Submit(formData, options).then((res) => {
        if (res.code !== 0) {
          config.onError(res.message || '上传失败');
          return;
        }
        config.onSuccess(res);
      });
    } catch (e) {
      config.onError(e);
    }
  };

  const handleBeforeUpload = (file: RcFile) => {
    if (file.size <= 0) {
      messageApi.error('文件为空');
      return false;
    }
    return true;
  };

  return (
    <>
      <Upload
        multiple={props.multiple || false}
        maxCount={9}
        accept="*/*"
        showUploadList={props.showUploadList || false}
        disabled={props.disabled || false}
        beforeUpload={handleBeforeUpload}
        customRequest={handleCustomRequest}
        onChange={handleChange}
      >
        <Button size={props.btnSize} title={props.btnTitle}>
          {props.btnChild || <CloudUploadOutlined />}
        </Button>
      </Upload>
      {contextHolder}
    </>
  );
};

export default ButtonUpload;
